{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ResidueSelectors范围选择器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "氨基酸选择器(ResidueSelector)具有十分重要的功能。它能够从蛋白质结构(Pose)中选取并生成氨基酸子集。一旦生成了这些子集，对后续建模的逻辑操作具有重大的意义，比如可以定义设计或采样的自由度（使用ResidueSelector可以将蛋白质距离内核中心5埃范围内的氨基酸选择出来，后续进行氨基酸侧链能量最小化等结构优化），也可以配合**SimpleMetrics**、**Filter**等进行蛋白质性质或参数的统计。\n",
    "\n",
    "注: ResidueSelectors的概念比较简单也比较利于初学者理解，因此此章节学习难度较小。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. ResidueSelector与vector1_bool"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在PyRosetta中，定义好ResidueSelectors后，进行apply(可以理解为执行选择的过程)，我们将得到氨基酸残基的子集列表。这个列表被保存在vector1<bool>对象中，以下以具体的实例进行讲解:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyRosetta-4 2020 [Rosetta PyRosetta4.conda.mac.python37.Release 2020.02+release.22ef835b4a2647af94fcd6421a85720f07eddf12 2020-01-05T17:31:56] retrieved from: http://www.pyrosetta.org\n",
      "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n",
      "\u001b[0mcore.init: {0} \u001b[0mChecking for fconfig files in pwd and ./rosetta/flags\n",
      "\u001b[0mcore.init: {0} \u001b[0mRosetta version: PyRosetta4.conda.mac.python37.Release r242 2020.02+release.22ef835b4a2 22ef835b4a2647af94fcd6421a85720f07eddf12 http://www.pyrosetta.org 2020-01-05T17:31:56\n",
      "\u001b[0mcore.init: {0} \u001b[0mcommand: PyRosetta -ex1 -ex2aro -database /opt/miniconda3/lib/python3.7/site-packages/pyrosetta/database\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0m'RNG device' seed mode, using '/dev/urandom', seed=437453851 seed_offset=0 real_seed=437453851 thread_index=0\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0mRandomGenerator:init: Normal mode, seed=437453851 RG_type=mt19937\n",
      "\u001b[0mcore.import_pose.import_pose: {0} \u001b[0mFile './data/6LZ9_H_L.pdb' automatically determined to be of type PDB\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 21 94\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 21 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 94 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 21 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 94 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mFound disulfide between residues 141 206\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 141 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 206 CYS\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 141 CYD\n",
      "\u001b[0mcore.conformation.Conformation: {0} \u001b[0mcurrent variant for 206 CYD\n"
     ]
    }
   ],
   "source": [
    "# 导入链选择器\n",
    "from pyrosetta import pose_from_pdb, init\n",
    "from pyrosetta.rosetta.core.select.residue_selector import ChainSelector\n",
    "\n",
    "init()\n",
    "# 从pdb中读入生成pose对象，(肝细胞生长因子抗体PDB:6LZ9)\n",
    "pose = pose_from_pdb('./data/6LZ9_H_L.pdb')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "抗体含有的链数量:2\n",
      "抗体含有的氨基酸数量:223\n"
     ]
    }
   ],
   "source": [
    "# 先来看看抗体的基本信息:\n",
    "print(f'抗体含有的链数量:{pose.num_chains()}')\n",
    "print(f'抗体含有的氨基酸数量:{pose.total_residue()}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择抗体的重链，PDB链号为\"H\":\n",
    "select_heavy_chain = ChainSelector('H')\n",
    "select_heavy_chain.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 H \n",
      "105 L \n"
     ]
    }
   ],
   "source": [
    "# 查看1号和223号氨基酸的PDB信息:\n",
    "print(pose.pdb_info().pose2pdb(1))\n",
    "print(pose.pdb_info().pose2pdb(223))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**</br>\n",
    "知识点1: vector1_bool中被选择的氨基酸返回“1”，而没有被选择的氨基酸返回“0”</br>\n",
    "知识点2: vector1_bool中是按照Pose编号进行编写的(从1开开始)，也就是说重链的编号从1 -> n, 轻链的编号从n+1 -> 223."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. ResidueSelector的基本分类\n",
    "\n",
    "氨基酸选择器按功能可分为三大类:\n",
    "\n",
    "- 逻辑选择器\n",
    "- 非构象依赖选择器\n",
    "- 构象依赖选择器\n",
    "\n",
    "以下我们将逐步来讲解在实战中，都有哪些氨基酸选择可以为我们所用。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.1 逻辑选择器\n",
    "第一部分是逻辑选择器，很好理解，按照逻辑分类为Not、And、Or逻辑关系，可以将**两个**选择器进行逻辑的再次选择。\n",
    "在Rosetta中，负责逻辑定义的选择器为NotResidueSelector、AndResidueSelector、OrResidueSelector。\n",
    "以下做实例说明:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 还是以之前读入的抗体pose为例。\n",
    "# 先定义Selector:\n",
    "select_heavy_chain = ChainSelector('H')\n",
    "select_light_chain = ChainSelector('L')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择重链，并生成氨基酸子集\n",
    "select_heavy_chain.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择轻链，并生成氨基酸子集\n",
    "select_light_chain.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择轻链**或**重链\n",
    "from pyrosetta.rosetta.core.select.residue_selector import OrResidueSelector\n",
    "light_or_heavy = OrResidueSelector(select_heavy_chain, select_light_chain)\n",
    "light_or_heavy.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**:</br>\n",
    "可见vector1_bool返回了所有的氨基酸，因为pose中只有重链和轻链，因此或逻辑返回了所有的氨基酸"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 选择重链**且**轻链\n",
    "from pyrosetta.rosetta.core.select.residue_selector import AndResidueSelector\n",
    "light_and_heavy = AndResidueSelector(select_heavy_chain, select_light_chain)\n",
    "light_and_heavy.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**:</br>\n",
    "可见vector1_bool的子集列表全为0，因为重链和轻链是独立的两条链，不存在”且“的关系。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 非选择器:\n",
    "from pyrosetta.rosetta.core.select.residue_selector import NotResidueSelector\n",
    "not_heavy = NotResidueSelector(select_heavy_chain)\n",
    "not_heavy.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**:</br>\n",
    "可见vector1_bool的返回了轻链的氨基酸子集（非重链的部分）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2 非构象依赖的选择器\n",
    "这类选择器的定义不依赖于具体的构象，仅仅依靠属性就可以定义。如链的选择、选择某号氨基酸、选择带电氨基酸等。以下将逐一介绍这些选择器，以及其使用的方法:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.1 ResidueIndexSelector\n",
    "通过氨基酸的具体编号定义的选择器，不仅可以使用PDB编号、Pose编号，还可以指定氨基酸的范围进行选择。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import ResidueIndexSelector\n",
    "# 根据具体的编号选择:\n",
    "pose_index_selector = ResidueIndexSelector('1,3,5')\n",
    "pose_index_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 根据具体的PDB编号选择, 注意需要附带上PDB链的信息。\n",
    "pdb_index_selector = ResidueIndexSelector('2H,3H,4H')\n",
    "pdb_index_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 根据PDB的范围进行选择。\n",
    "range_selector = ResidueIndexSelector('2H-20H')\n",
    "range_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.2 ResidueNameSelector\n",
    "通过氨基酸的具体残基名定义的选择器:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Resname selector; 残基名称选择器\n",
    "from pyrosetta.rosetta.core.select.residue_selector import *\n",
    "resname_selector = ResidueNameSelector('PHE')\n",
    "resname_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Resname selector; 残基名称选择器, 根据多个残基名进行选择:\n",
    "resname_selector = ResidueNameSelector('PHE,ASN')\n",
    "resname_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Resname selector; 选择带修饰的氨基酸残基\n",
    "resname_selector = ResidueNameSelector('CYS')\n",
    "resname_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Residue 21: CYS:disulfide (CYS, C):\n",
      "Base: CYS\n",
      " Properties: POLYMER PROTEIN CANONICAL_AA SC_ORBITALS METALBINDING DISULFIDE_BONDED ALPHA_AA L_AA\n",
      " Variant types: DISULFIDE\n",
      " Main-chain atoms:  N    CA   C  \n",
      " Backbone atoms:    N    CA   C    O    H    HA \n",
      " Side-chain atoms:  CB   SG  1HB  2HB \n",
      "Atom Coordinates:\n",
      "   N  : 41.714, 50.854, 39.059\n",
      "   CA : 40.257, 50.826, 39.06\n",
      "   C  : 39.723, 49.899, 37.976\n",
      "   O  : 39.898, 50.156, 36.784\n",
      "   CB : 39.691, 52.23, 38.847\n",
      "   SG : 37.891, 52.332, 38.998\n",
      "   H  : 42.196, 51.355, 38.325\n",
      "   HA : 39.919, 50.458, 40.029\n",
      "  1HB : 40.13, 52.913, 39.575\n",
      "  2HB : 39.967, 52.587, 37.855\n",
      "Mirrored relative to coordinates in ResidueType: FALSE\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(pose.residue(21))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**</br>\n",
    "选择带二硫键的氨基酸时，使用CYS残基名并没有正确选择到对应的氨基酸，因为在Rosetta中，形成二硫键的半胱氨酸名为CYS:\n",
    "CYS:disulfide, 接下来我们尝试换个名字进行选择."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "resname_selector = ResidueNameSelector('CYS:disulfide')\n",
    "resname_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**</br>\n",
    "现在可以正确选择到对应的二硫键氨基酸子集了！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.2 ResiduePropertySelector\n",
    "通过氨基酸的性质进行定义的选择器，比如可以选择带正电的氨基酸、带负电的氨基酸、疏水氨基酸、含有芳香环的氨基酸等等。</br>\n",
    "氨基酸的性质分类可详见: https://www.rosettacommons.org/docs/latest/scripting_documentation/RosettaScripts/ResidueSelectors/ResiduePropertySelector\n",
    "\n",
    "以下以实例进行说明:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1]"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import ResiduePropertySelector\n",
    "from pyrosetta.rosetta.core.chemical import ResidueProperty\n",
    "\n",
    "# example1: 使用单一属性选择，选择所有的极性氨基酸\n",
    "prop_selector = ResiduePropertySelector(ResidueProperty.POLAR)\n",
    "prop_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import basic_selection_logic\n",
    "# example2: 使用多属性进行选择\n",
    "prop_selector = ResiduePropertySelector()\n",
    "prop_selector.add_property(ResidueProperty.POLAR)  # 极性氨基酸\n",
    "prop_selector.add_property(ResidueProperty.CHARGED) # 带电的氨基酸\n",
    "prop_selector.set_selection_logic(basic_selection_logic.or_logic)\n",
    "prop_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**结果解读**</br>\n",
    "注意在使用多属性选择时，应当注意选择的逻辑性，可通过set_selection_logic进行设置，默认为AND逻辑。如果设置为OR逻辑需要使用basic_selection_logic.or_logic."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.3 RandomResidueSelector\n",
    "从某个氨基酸子集中随机地选取N个氨基酸定义的选择器。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.select.residue_selector.RandomResidueSelector: {0} \u001b[0mSelected residues: 19 56 113 105 82 44 98 24 43 23 22 39 38 29 15 10 26 5 34 37 110 65 49 57 119 80 32 3 73 11\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import RandomResidueSelector\n",
    "\n",
    "# 比如从重链中随机选择出5个氨基酸: 多运行几次，就可发现返回的编号是不一样的。\n",
    "random_selector = RandomResidueSelector(select_heavy_chain, 30)\n",
    "random_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.4 Antibody相关的选择器\n",
    "也有一些选择器是根据分子类型开发的，比如在RosettaAntibody模块中，就有特定选择CDR氨基酸的选择器。比如CDRResidueSelector、AntibodyRegionSelector等。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. CDRResidueSelector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyrosetta.rosetta.protocols.antibody import CDRNameEnum\n",
    "from rosetta.protocols.antibody.residue_selector import CDRResidueSelector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PyRosetta-4 2020 [Rosetta PyRosetta4.conda.mac.python37.Release 2020.02+release.22ef835b4a2647af94fcd6421a85720f07eddf12 2020-01-05T17:31:56] retrieved from: http://www.pyrosetta.org\n",
      "(C) Copyright Rosetta Commons Member Institutions. Created in JHU by Sergey Lyskov and PyRosetta Team.\n",
      "\u001b[0mcore.init: {0} \u001b[0mChecking for fconfig files in pwd and ./rosetta/flags\n",
      "\u001b[0mcore.init: {0} \u001b[0mRosetta version: PyRosetta4.conda.mac.python37.Release r242 2020.02+release.22ef835b4a2 22ef835b4a2647af94fcd6421a85720f07eddf12 http://www.pyrosetta.org 2020-01-05T17:31:56\n",
      "\u001b[0mcore.init: {0} \u001b[0mcommand: PyRosetta -input_ab_scheme Chothia -database /opt/miniconda3/lib/python3.7/site-packages/pyrosetta/database\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0m'RNG device' seed mode, using '/dev/urandom', seed=-1409532468 seed_offset=0 real_seed=-1409532468 thread_index=0\n",
      "\u001b[0mbasic.random.init_random_generator: {0} \u001b[0mRandomGenerator:init: Normal mode, seed=-1409532468 RG_type=mt19937\n"
     ]
    }
   ],
   "source": [
    "init('-input_ab_scheme Chothia') # 根据抗体的不同编号进行选择初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mbasic.io.database: {0} \u001b[0mDatabase file opened: sampling/antibodies/cluster_center_dihedrals.txt\n",
      "\u001b[0mprotocols.antibody.AntibodyNumberingParser: {0} \u001b[0mAntibody numbering scheme definitions read successfully\n",
      "\u001b[0mprotocols.antibody.AntibodyNumberingParser: {0} \u001b[0mAntibody CDR definition read successfully\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSuccessfully finished the CDR definition\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Detecting Regular CDR H3 Stem Type\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mTRDGGLLFAYYAMDYW\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Finished Detecting Regular CDR H3 Stem Type: KINKED\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Finished Detecting Regular CDR H3 Stem Type: Kink: 1 Extended: 0\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H1\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 13 Omega: TTTTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H2\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 9 Omega: TTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H3\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 15 Omega: TTTTTTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L1\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 11 Omega: TTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L2\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 8 Omega: TTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L3\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 9 Omega: TTTTTTCTT\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example1: 选择单个CDR.\n",
    "cdr_selector = CDRResidueSelector()\n",
    "cdr_selector.set_cdr(CDRNameEnum.h1)  #h1,h2,h3,l1,l2,l3\n",
    "cdr_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mbasic.io.database: {0} \u001b[0mDatabase file opened: sampling/antibodies/cluster_center_dihedrals.txt\n",
      "\u001b[0mprotocols.antibody.AntibodyNumberingParser: {0} \u001b[0mAntibody numbering scheme definitions read successfully\n",
      "\u001b[0mprotocols.antibody.AntibodyNumberingParser: {0} \u001b[0mAntibody CDR definition read successfully\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSuccessfully finished the CDR definition\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Detecting Regular CDR H3 Stem Type\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mTRDGGLLFAYYAMDYW\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Finished Detecting Regular CDR H3 Stem Type: KINKED\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Finished Detecting Regular CDR H3 Stem Type: Kink: 1 Extended: 0\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H1\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 13 Omega: TTTTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H2\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 9 Omega: TTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H3\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 15 Omega: TTTTTTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L1\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 11 Omega: TTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L2\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 8 Omega: TTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L3\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 9 Omega: TTTTTTCTT\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example2: 选择多个CDR\n",
    "from pyrosetta.rosetta.utility import vector1_protocols_antibody_CDRNameEnum\n",
    "\n",
    "# 设定cdr list;\n",
    "cdrs_list = vector1_protocols_antibody_CDRNameEnum()\n",
    "cdrs_list.append(CDRNameEnum.h1) # 添加cdr-h1\n",
    "cdrs_list.append(CDRNameEnum.h2) # 添加cdr-h2\n",
    "cdrs_list.append(CDRNameEnum.h3) # 添加cdr-h3\n",
    "\n",
    "cdr_selector = CDRResidueSelector()\n",
    "cdr_selector.set_cdrs(cdrs_list)\n",
    "cdr_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. AntibodyRegionSelector\n",
    "除了选择CDR，还可以通过抗体的区域选择器选择Framework区、抗体antigen等区域。\n",
    "使用AntibodyRegionSelector选择器需要额外定义好AntibodyRegionEnum:\n",
    "- antigen_region\n",
    "- cdr_region\n",
    "- framework_region"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mbasic.io.database: {0} \u001b[0mDatabase file opened: sampling/antibodies/cluster_center_dihedrals.txt\n",
      "\u001b[0mprotocols.antibody.AntibodyNumberingParser: {0} \u001b[0mAntibody numbering scheme definitions read successfully\n",
      "\u001b[0mprotocols.antibody.AntibodyNumberingParser: {0} \u001b[0mAntibody CDR definition read successfully\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSuccessfully finished the CDR definition\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Detecting Regular CDR H3 Stem Type\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mTRDGGLLFAYYAMDYW\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Finished Detecting Regular CDR H3 Stem Type: KINKED\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mAC Finished Detecting Regular CDR H3 Stem Type: Kink: 1 Extended: 0\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H1\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 13 Omega: TTTTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H2\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 9 Omega: TTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for H3\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 15 Omega: TTTTTTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L1\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 11 Omega: TTTTTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L2\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 8 Omega: TTTTTTTT\n",
      "\u001b[0mantibody.AntibodyInfo: {0} \u001b[0mSetting up CDR Cluster for L3\n",
      "\u001b[0mprotocols.antibody.cluster.CDRClusterMatcher: {0} \u001b[0mLength: 9 Omega: TTTTTTCTT\n"
     ]
    }
   ],
   "source": [
    "# 抗体区域选择器:\n",
    "from pyrosetta.rosetta.protocols.antibody import AntibodyRegionEnum\n",
    "from pyrosetta.rosetta.protocols.antibody.residue_selector import AntibodyRegionSelector\n",
    "ab_region_selector = AntibodyRegionSelector()\n",
    "ab_region_selector.set_region(AntibodyRegionEnum.cdr_region)\n",
    "ab_region_selector.apply(pose)\n",
    "\n",
    "# 读者也可以尝试设置以下的一些选项试试。\n",
    "ab_region_selector.set_region(framework_region)\n",
    "ab_region_selector.set_region(antigen_region)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.2.5 糖分子相关的选择器\n",
    "糖分子的建模也是近期Rosetta兼容的对象之一，现在有几个专门地选择器GlycanResidueSelector、GlycanLayerSelector、RandomGlycanFoliageSelector。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "#略"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 构象依赖的选择器\n",
    "顾名思义，这类选择器与分子结构的具体构象有关，具体地由二面角、二级结构、氢键、邻居分子数量、相互作用界面、对称性等几个层次去进行定义。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.1 InterGroupInterfaceByVectorSelector\n",
    "该选择器使用氨基酸Cα-Cβ向量的长度以及角度来搜索两个刚体之间相互接触的氨基酸, 其中nearby_atom_cut和vector_dist_cut是关键的距离参数，距离越大，选择的相互作用界面越大。默认为6和8埃。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import InterGroupInterfaceByVectorSelector\n",
    "interface_seletor = InterGroupInterfaceByVectorSelector(select_light_chain, select_heavy_chain)\n",
    "interface_seletor.nearby_atom_cut(6)\n",
    "interface_seletor.vector_dist_cut(8)\n",
    "interface_seletor.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.2 LayerSelector\n",
    "Layer是Rosetta中的一个重要概念，将蛋白质分为表面层(surface)、交界层(boundary)以及内核层(Core)。众所周知，蛋白质的不同层的氨基酸是具有偏好性分布的，比如在内核层由许多的非极性氨基酸组成的疏水核心，而在表面层分布大多为极性氨基酸，能与溶液环境中的水分子相互作用。LayerSelector是十分强大的工具，可以根据set_layers()进行组合选择。set_layers()的三个布尔值按顺序分别代表选择Core/boundary/Surface。另外该选择器有两种判别模式（只能选其一），分别是基于SASA的方法和基于邻居数量的方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting LayerSelector to use sidechain neighbors to determine burial.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSet cutoffs for core and surface to 5.2 and 2, respectively, in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting core=true boundary=false surface=false in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting core=false boundary=true surface=false in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting core=false boundary=false surface=true in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting LayerSelector to use sidechain neighbors to determine burial.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSet cutoffs for core and surface to 5.2 and 2, respectively, in LayerSelector.\n"
     ]
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import LayerSelector\n",
    "layer_selector = LayerSelector()\n",
    "\n",
    "# 定义需要选定的层:\n",
    "layer_selector.set_layers(True, False, False) # 只选择内核的设置方法\n",
    "layer_selector.set_layers(False, True, False) # 只选择边界层的设置方法\n",
    "layer_selector.set_layers(False, False, True) # 只选择表面层的设置方法 \n",
    "\n",
    "# neighbor-based(选1，根据set_use_sc_neighbors)\n",
    "layer_selector.set_use_sc_neighbors(False) # 使用Sidechain neighbor算法，否则使用SASA-based算法，确定内核残基。\n",
    "layer_selector.set_cutoffs(5.2, 2.0) # 内核,表层邻居数量截断设置\n",
    "\n",
    "# neighbor-based(选1，根据set_use_sc_neighbors)\n",
    "layer_selector.set_use_sc_neighbors(True)\n",
    "layer_selector.set_cutoffs(5.2, 2.0) # 内核,表层邻居数量截断设置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting LayerSelector to use sidechain neighbors to determine burial.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSet cutoffs for core and surface to 5.2 and 2, respectively, in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting core=true boundary=false surface=false in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting LayerSelector to use rolling ball-based occlusion to determine burial.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSet cutoffs for core and surface to 20 and 40, respectively, in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting radius for rolling ball algorithm to 2 in LayerSelector.  (Note that this will have no effect if the sidechain neighbors method is used.)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0]"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example1: 选择内核层(SASA法)\n",
    "layer_selector = LayerSelector()\n",
    "layer_selector.set_layers(True, False, False) # 只选择内核的设置方法\n",
    "layer_selector.set_use_sc_neighbors(False) # 使用Sidechain neighbor算法，否则使用SASA-based算法，确定内核残基。\n",
    "layer_selector.set_cutoffs(20.0, 40.0) # 内核,表层截断半径设置\n",
    "layer_selector.set_ball_radius(2.0) # 传统值为1.4\n",
    "layer_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting LayerSelector to use sidechain neighbors to determine burial.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSet cutoffs for core and surface to 5.2 and 2, respectively, in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting core=false boundary=false surface=true in LayerSelector.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSetting LayerSelector to use sidechain neighbors to determine burial.\n",
      "\u001b[0mcore.select.residue_selector.LayerSelector: {0} \u001b[0mSet cutoffs for core and surface to 5.2 and 2, respectively, in LayerSelector.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1]"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# example2: 选择表面层(侧链法)\n",
    "layer_selector = LayerSelector()\n",
    "layer_selector.set_layers(False, False, True) # 只选择内核的设置方法\n",
    "layer_selector.set_use_sc_neighbors(True) # 使用Sidechain neighbor算法，否则使用SASA-based算法，确定内核残基。\n",
    "layer_selector.set_cutoffs(5.2, 2.0) # 内核,表层邻居数量截断设置\n",
    "layer_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.3 二面角相关选择器\n",
    "在Rosetta中，二面角作为描述蛋白骨架结构最重要的参数，当然少不了与二面角数据有关的选择器。此处主要介绍BinSelector、PhiSelector。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. BinSelector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "ABEGO系统在Rosetta中也是比较重要的概念，是从Ramachandran-plot的分布区间进行定义的离散模型, 坐标轴分别定义了phi/psi角，用于描述蛋白局部骨架结构的构象。\n",
    "ABEGO的每个字母代表一个区间, 这些区间的分布是有二级结构的偏向性的:\n",
    "- A: 二面角分布多见于右手性的α螺旋\n",
    "- B: 二面角分布多见于右手性的β折叠\n",
    "- E: 二面角分布多见于左手性的β折叠（罕见）\n",
    "- G: 二面角分布多见于左手性的螺旋（罕见）\n",
    "- O: 反式的omega分布，多见于反式脯氨酸\n",
    "\n",
    "L-氨基酸的二面角的分布频率可见下图（D-氨基酸的分布频率为镜像）:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](./img/Coarse-grained-representation-of-the-Ramachandran-plot-based-on-ABEGO-torsion-bins-ABEGO.jpg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mbasic.io.database: {0} \u001b[0mDatabase file opened: protocol_data/generalizedKIC/bin_params/ABEGO.bin_params\n",
      "\u001b[0mcore.scoring.bin_transitions.BinTransitionCalculator: {0} \u001b[0mOpened file protocol_data/generalizedKIC/bin_params/ABEGO.bin_params for read.\n",
      "\u001b[0mcore.scoring.bin_transitions.BinTransitionCalculator: {0} \u001b[0mFinished read of protocol_data/generalizedKIC/bin_params/ABEGO.bin_params.\n",
      "\u001b[0mcore.select.residue_selector.BinSelector: {0} \u001b[0mLoaded bin parameters file \"ABEGO\" and set bin to select to \"A\".  Only selecting alpha-amino acids.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 将满足phi、psi落在某个区间骨架二面角的残基选出。\n",
    "from pyrosetta.rosetta.core.select.residue_selector import BinSelector\n",
    "bin_selector = BinSelector()\n",
    "bin_selector.set_bin_name('A') # 选择落在A区域的氨基酸\n",
    "bin_selector.set_bin_params_file_name('ABEGO')\n",
    "bin_selector.initialize_and_check() # 必须先启动\n",
    "bin_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. PhiSelector\n",
    "根据Ramachandran空间某一坐标轴的正负值，进行选择氨基酸。</br>\n",
    "该选择器**有特定的应用场景**，比如在环肽设计中，通常会混合D-/L-氨基酸。那这些氨基酸的ABGEO分布式对称的，一般用甘氨酸作为出发的氨基酸进行骨架采样，当骨架phi为正值时，这些位置就可以设计为D型氨基酸，而phi为负值时，设计为L型氨基酸。这种设计方案显得更有\"物理\"意义。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import PhiSelector\n",
    "phi_selector = PhiSelector()\n",
    "phi_selector.set_select_positive_phi(True)  # True=select +phi\n",
    "phi_selector.set_ignore_unconnected_upper(True)\n",
    "phi_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 3. PsiSelector\n",
    "没有这个选择器...有兴趣的读者可以尝试自己写一个。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.4 邻居相关的选择器\n",
    "邻居的概念应用十分广泛，比如我想选择酶活中心周围8埃距离范围内的所有氨基酸等，该选择器对区域性设计时十分有用！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 1. NeighborhoodResidueSelector\n",
    "有两种用法，第一种选择半径范围内所有的氨基酸，第二种为选择**邻近范围内**的氨基酸"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m ################ Cloning pose and building neighbor graph ################\n",
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m Ensure that pose is either scored or has update_residue_neighbors() called\n",
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m before using NeighborhoodResidueSelector for maximum performance!\n",
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m ##########################################################################\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 比如我想选择1号氨基酸范围内10埃所有的氨基酸(包括1号氨基酸):\n",
    "from pyrosetta.rosetta.core.select.residue_selector import NeighborhoodResidueSelector, ResidueIndexSelector\n",
    "residue1_selector = ResidueIndexSelector('1')\n",
    "nbr_selector = NeighborhoodResidueSelector(residue1_selector, 10.0, True)  # True 代表包括1号氨基酸。\n",
    "nbr_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m ################ Cloning pose and building neighbor graph ################\n",
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m Ensure that pose is either scored or has update_residue_neighbors() called\n",
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m before using NeighborhoodResidueSelector for maximum performance!\n",
      "\u001b[0mcore.select.residue_selector.NeighborhoodResidueSelector: {0} \u001b[0m\u001b[1m[ WARNING ]\u001b[0m ##########################################################################\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"
      ]
     },
     "execution_count": 83,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 比如我想选择1号氨基酸范围内10埃所有的氨基酸(不包括1号氨基酸):\n",
    "nbr_selector = NeighborhoodResidueSelector(residue1_selector, 10.0, False)  # True 代表包括1号氨基酸。\n",
    "nbr_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 2. NumNeighborsSelector\n",
    "不同于NeighborhoodResidueSelector，NumNeighborsSelector只会将周围邻居氨基酸超过设定阈值部分的氨基酸位点选出，对于选择氨基酸密度高的区域比较有用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "vector1_bool[0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from pyrosetta.rosetta.core.select.residue_selector import NumNeighborsSelector\n",
    "nn_selector = NumNeighborsSelector(15, 10.0)  # 两个参数分别是邻居数量阈值、距离半径阈值\n",
    "nn_selector.count_water(True)  # 甚至还可以考虑水分子的数量.\n",
    "nn_selector.apply(pose)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 3. CloseContactResidueSelector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.3.5 一、二级结构相关的选择器\n",
    "基于一、二级结构的选择器种类丰富:\n",
    "- PrimarySequenceNeighborhoodSelector\n",
    "- SSElementSelector\n",
    "- SecondaryStructureSelector\n",
    "- PairedSheetResidueSelector"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### PrimarySequenceNeighborhoodSelector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "TaskSelector"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
